﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using SharpPopulatorLib;
using System.Reflection;

namespace SharpPopulator.Forms
{

    public partial class frmPopulatorV2 : Form
    {

        #region Atributes

        ConfiguredFieldCollection _ConfiguredFields;
        List<DBField> _Fields;
        List<String> _FieldNames;
        //Populator _Populator;
        SharpPopulatorLib.Populator _objPopulator;
        
        #endregion

        #region Constructors

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tables"></param>
        public frmPopulatorV2(List<String> tables)
        {
            InitializeComponent();
            cbTables.DataSource = tables;
            cbTypes.Items.AddRange(Enum.GetNames(typeof(NativeDataType)));
            cbStringExpression.Items.AddRange(Enum.GetNames(typeof(StringsExpressionsType)));
        }

        #endregion

        #region Events

        /// <summary>
        /// To obtain the field's names
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbTables_SelectedIndexChanged(object sender, EventArgs e)
        {
            //To obtain the field's names
            //_Fields = DBManager.GetFields(cbTables.Text.ToString(), Settings.ConnectionString);

            _Fields = DBManager.GetFields(cbTables.Text.ToString(), Settings.ConnectionString, true);

            LoadFields(_Fields);

            var _ListFieldsNames = from _fieldname in _Fields
                                   select _fieldname.Name;

            _FieldNames = new List<String>();
            foreach (var _field in _ListFieldsNames)
            { _FieldNames.Add(_field); }
            
            if (_ConfiguredFields == null)
            { _ConfiguredFields = new  ConfiguredFieldCollection(); }

            _ConfiguredFields.Clear();

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            //
            Boolean _PrimaryKeyField = false;

            switch ((NativeDataType)Enum.Parse(typeof(NativeDataType), cbTypes.Text.ToString()))
            {
                case NativeDataType.DATE:
                {
                    cbStringExpression.Enabled = false;
                    cbStringExpression.Text = "";
                    pgConfiguration.SelectedObject = new DateProperties();
                }
                break;
                case NativeDataType.INT:
                {
                    cbStringExpression.Enabled = false;
                    cbStringExpression.Text = "";
                    try
                    {
                        if (_Fields[lvFields.SelectedIndices[0]].IsPrimaryKey)
                        { _PrimaryKeyField = true; }
                        else
                        { _PrimaryKeyField = false; }
                        pgConfiguration.SelectedObject = new IntProperties(_PrimaryKeyField, 0, (Int32)nudRecords.Value, _PrimaryKeyField);
                        pgConfiguration.Enabled = !_PrimaryKeyField;
                    }
                    catch (ArgumentOutOfRangeException ex)
                    {
                        //pgConfiguration.SelectedObject = new IntProperties(_PrimaryKeyField, 0, (Int32)nudRecords.Value, false);
                        //pgConfiguration.Enabled = true;
                        MessageBox.Show("Please select a field from the list", "SharpPopulator says", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        lvFields.Focus();
                    }
                    catch (Exception)
                    { throw; }
                }
                break;
                case NativeDataType.VARCHAR:
                {
                    cbStringExpression.Enabled = true;
                    cbStringExpression.Focus();
                }
                break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbStringExpression_SelectedIndexChanged(object sender, EventArgs e)
        {
            //
            switch ((StringsExpressionsType)Enum.Parse(typeof(StringsExpressionsType), cbStringExpression.Text.ToString()))
            {
                case StringsExpressionsType.EMAIL:
                { pgConfiguration.SelectedObject = new DomainProperties(); }
                break;
                case StringsExpressionsType.FULLNAME:
                { pgConfiguration.SelectedObject = new StringProperties((StringsExpressionsType)Enum.Parse(typeof(StringsExpressionsType), cbStringExpression.Text.ToString())); }
                break;
                case StringsExpressionsType.LASTNAME:
                { pgConfiguration.SelectedObject = new StringProperties((StringsExpressionsType)Enum.Parse(typeof(StringsExpressionsType), cbStringExpression.Text.ToString())); }
                break;
                case StringsExpressionsType.NAME:
                { pgConfiguration.SelectedObject = new StringProperties((StringsExpressionsType)Enum.Parse(typeof(StringsExpressionsType), cbStringExpression.Text.ToString())); }
                break;
                case StringsExpressionsType.PASSWORD:
                { pgConfiguration.SelectedObject = new EncriptationProperties(); }
                break;
                case StringsExpressionsType.TEXT:
                { pgConfiguration.SelectedObject = new StringProperties((StringsExpressionsType)Enum.Parse(typeof(StringsExpressionsType), cbStringExpression.Text.ToString())); }
                break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnKeep_Click(object sender, EventArgs e)
        {
            //
            ConfigurationPropertiesType _ConfigurationType = ConfigurationPropertiesType.String;
            ConfiguredField _PreConfiguredField;

            if (!cbStringExpression.Enabled)
            { 
                switch ((NativeDataType) Enum.Parse(typeof(NativeDataType), cbTypes.Text.ToString()))
                {
                    case NativeDataType.DATE:
                    { _ConfigurationType = ConfigurationPropertiesType.Date; }
                    break;
                    case NativeDataType.INT:
                    { _ConfigurationType = ConfigurationPropertiesType.Int; }
                    break;
                    case NativeDataType.VARCHAR:
                    {  }
                    break;
                }
            }
            else
            {
                switch((StringsExpressionsType) Enum.Parse(typeof(StringsExpressionsType), cbStringExpression.Text))
                {
                    case StringsExpressionsType.EMAIL:
                    { _ConfigurationType = ConfigurationPropertiesType.Domain; }
                    break;
                    case StringsExpressionsType.FULLNAME:
                    { _ConfigurationType = ConfigurationPropertiesType.String; }
                    break;
                    case StringsExpressionsType.LASTNAME:
                    { _ConfigurationType = ConfigurationPropertiesType.String; } 
                    break;
                    case StringsExpressionsType.NAME:
                    { _ConfigurationType = ConfigurationPropertiesType.String; }
                    break;
                    case StringsExpressionsType.PASSWORD:
                    { _ConfigurationType = ConfigurationPropertiesType.Encriptation; }
                    break;
                    case StringsExpressionsType.TEXT:
                    { _ConfigurationType = ConfigurationPropertiesType.String; }
                    break;
                }
            }

            try
            {
                _PreConfiguredField = new ConfiguredField(tbSelectedField.Text.ToString(), pgConfiguration.SelectedObject, _ConfigurationType, _Fields[lvFields.SelectedIndices[0]].IsPrimaryKey);
                if (_ConfiguredFields.Exist(tbSelectedField.Text.ToString()))
                { _ConfiguredFields[_PreConfiguredField].Configuration = _PreConfiguredField; }
                else
                { _ConfiguredFields.Add(_PreConfiguredField); }
                MessageBox.Show("Field kept", "SharpPopulator says", MessageBoxButtons.OK, MessageBoxIcon.Information); 
            }
            catch (Exception ex)
            { MessageBox.Show(ex.Message, "Ops", MessageBoxButtons.OK, MessageBoxIcon.Error); }
           
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnGenerate_Click(object sender, EventArgs e)
        {
            //
            if (_ConfiguredFields.Count > 0)
            { 
                if ((Int32) nudRecords.Value > 0)
                {
                    try
                    { 
                        TryPropulate();
                        MessageBox.Show("The script has been created", "SharpPopulator says", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    { 
                        MessageBox.Show(ex.Message, "SharpPopulator says", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    }

                }
                else
                { epError.SetError(nudRecords, "Maybe you want to generate some records."); }
            }
            else
            { epError.SetError(btnGenerate, "Maybe you want to configure the fields."); }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lvFields_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            String _FieldName;
            tbSelectedField.Text = e.Item.Text;

            if (_ConfiguredFields != null)
            {
                _FieldName = tbSelectedField.Text.ToString();
                if (_ConfiguredFields.Exist(_FieldName))
                {
                    pgConfiguration.SelectedObject = _ConfiguredFields[_FieldName].Configuration;
                    cbTypes.Text = _ConfiguredFields[_FieldName].Type.ToString().ToUpper();
                    if (cbTypes.Text == "STRING")
                    {
                        cbTypes.Text = NativeDataType.VARCHAR.ToString();
                        cbStringExpression.Text = ((StringProperties)_ConfiguredFields[_FieldName].Configuration).ExpressionType.ToString();
                    }
                }
                else
                {
                    cbTypes.Text = "";
                    cbStringExpression.Text = "";
                    pgConfiguration.SelectedObject = null;
                }
            }
        }

        #endregion              
                        
        #region Private Methods

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private Boolean TryPropulate()
        { 
            _objPopulator = new SharpPopulatorLib.Populator();
            _objPopulator.ConfiguredFields = _ConfiguredFields;
            _objPopulator.NumberOfRecords = (Int32) nudRecords.Value - 1;
            _objPopulator.TableName = cbTables.Text.ToString();
            try
            {
                _objPopulator.Populate();
                return true;
            }
            catch (Exception e)
            { throw; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_Fields"></param>
        private void LoadFields(List<DBField> _Fields)
        { 
            //To load the files to the ListView
            lvFields.Items.Clear();
            foreach (DBField _Field in _Fields)
            {
                if (_Field.IsPrimaryKey)
                { lvFields.Items.Add(_Field.Name, 1); }
                else
                { lvFields.Items.Add(_Field.Name); }
                
            }
        }

        #endregion
                
        #region Public Methods


        #endregion
        
    }

}
